/*
 * Author  : Leo <lipf160627@163.com>
 * Created : 2025-7-27
 * Desc    : ASR-PRO driver using USART
 */

#include "asrpro.hpp"
#include <stdint.h>

static const int RX_BUF_SIZE = 128; // 必须是128的倍数

Asrpro::Asrpro(uart_port_t uartNum, gpio_num_t pinTx, gpio_num_t pinRx, int baudRate)
    : m_uartNum(uartNum), m_pinTx(pinTx), m_pinRx(pinRx), m_baudRate(baudRate)
{
    this->init();
}

void Asrpro::init()
{
    const uart_config_t uart_config = {
        .baud_rate = this->m_baudRate,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_DEFAULT,
    };
    // We won't use a buffer for sending data.
    ESP_ERROR_CHECK(uart_driver_install(this->m_uartNum, RX_BUF_SIZE * 2, 0, 0, NULL, 0));
    ESP_ERROR_CHECK(uart_param_config(this->m_uartNum, &uart_config));
    ESP_ERROR_CHECK(uart_set_pin(this->m_uartNum, this->m_pinTx, this->m_pinRx, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
}

int Asrpro::sendData(const uint8_t* data, size_t len)
{
    return uart_write_bytes(this->m_uartNum, data, len);
}

int Asrpro::recvData(uint8_t* buffer, uint32_t bufferLen)
{
    return uart_read_bytes(this->m_uartNum, buffer, bufferLen, portMAX_DELAY);
}

bool Asrpro::sendCmd(uint8_t cmd)
{
    this->m_sendBuf = {0xAA, 0x55, cmd, 0x00};
    return uart_write_bytes(this->m_uartNum, this->m_sendBuf.data(), this->m_sendBuf.size()) == this->m_sendBuf.size();
}

bool Asrpro::sendAck(bool success)
{
    this->m_sendBuf = {0xAA, 0x55, ASRPRO_CMD_ACK, static_cast<uint8_t>(success ? 0x00 : 0x01)};
    return uart_write_bytes(this->m_uartNum, this->m_sendBuf.data(), this->m_sendBuf.size()) == this->m_sendBuf.size();
}

uint8_t Asrpro::recvCmd()
{
    uart_read_bytes(this->m_uartNum, this->m_recvBuf.data(), this->m_recvBuf.size(), portMAX_DELAY);
    return this->m_recvBuf[2];
}
